package dshop.action.admin;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.lang3.StringUtils;

import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import appbase.jfinal.ext.ApiBaseController;
import appbase.jfinal.ext.ModelKit;
import appbase.jfinal.ext.RecordKit;
import appbase.utils.JsonUtil;
import dshop.AppConst;
import dshop.interceptor.ApiAuthInterceptor;
import dshop.interceptor.ApiReadBodyParamInterceptor;
import dshop.model.Area;
import dshop.model.UserTag;
import dshop.model.company.Company;
import dshop.model.member.MemberGeneralInfo;
import dshop.model.procurement.IndustryCategory;
import dshop.model.procurement.Procurement;
import dshop.model.push.PushNum;
import dshop.model.push.PushRecord;
import dshop.model.push.PushUser;
import dshop.service.RedisService;
import dshop.service.RongCloudService;
import dshop.service.RongCloudService.ProcurementDto;
import dshop.service.SnsPushService;
import dshop.service.XingePushService;

/**
 * 采购管理
 */
@Before({ ApiReadBodyParamInterceptor.class, ApiAuthInterceptor.class })
public class ProcurementAction extends ApiBaseController {

	public void list() {
		String keyWord = getPara("keyWord", "").trim();
		String status = getPara("checkStatus", "").trim();

		// 排序
		String columnProp = getPara("columnProp", "").trim();
		String columnOrder = getPara("columnOrder", "").trim().split("ending")[0];

		String select = " select b.id, operator,operator_time,m.account_id,CONCAT(m.last_name,m.first_name) 'name', IF(company_name is null,'个人采购',company_name) company_name, address, "
				+ " contact_name, contact_phone, contact_email, "
				+ " product_name, product_description, buy_number, product_industry_name, product_specification, "
				+ " start_date_time, end_date_time,type, "
				+ " check_status, check_status_explain,check_date_time, add_date_time ,is_delete ";
		String where = " from bbs_procurement b left join member_general_info m on b.account_id = m.account_id "
				+ "  where 1=1 ";
		String orderBy = " ";

		List<Object> params = new ArrayList<Object>();
		if (!status.isEmpty()) {
			if (status.equals("END")) {
				where += " and end_date_time <= now() ";
				where += " and is_delete = 'NO' ";
			} else if (status.equals("DELETE")) {
				where += " and is_delete = 'YES' ";
			} else {
				where += " and check_status = ? ";
				where += " and is_delete = 'NO' ";
				params.add(status);
			}
		}
//		else {
//			where += " and is_delete = 'NO'";
//		}
		if (!keyWord.isEmpty()) {
			where += " and ( company_name like ? or contact_phone like ? or product_name like ?)";
			String keyWordParam = "%" + keyWord + "%";
			params.add(keyWordParam);
			params.add(keyWordParam);
			params.add(keyWordParam);
		}
		if (!columnOrder.isEmpty()) {
			orderBy += "order by " + columnProp + " " + columnOrder;
		} else {
			orderBy = " order by add_date_time desc ";
		}

		Page<Record> page = page(select, where + orderBy, params.toArray());
		List<Record> list = page.getList();

		Date now = new Date();
		for (Record r : list) {
			String product_name = r.getStr("product_name");
			String type = r.getStr("type");
			if ("PURCHASE".equals(type) && !product_name.startsWith("求购")) {// 求购
				r.set("product_name", "求购" + product_name);
			}
			if ("SEEK".equals(type) && !product_name.startsWith("寻求")) {// 寻求
				r.set("product_name", "寻求" + product_name);
			}
			Date endDate = r.getDate("end_date_time");
			if (endDate != null && now.after(endDate)) {
				r.set("is_time_out", AppConst.STATUS_VAL_YES);
			} else {
				r.set("is_time_out", AppConst.STATUS_VAL_NO);
			}
			r.set("is_push", 0);
		}
		List<PushRecord> pushRecords = PushRecord.findByProcurementIds(list);
		if (pushRecords != null && !pushRecords.isEmpty()) {
			for (PushRecord pushRecord : pushRecords) {
				for (Record r : list) {
					if (pushRecord.getInt("contentRefId").intValue() == r.getInt("id").intValue()) {
						r.set("is_push", 1);
					}
				}
			}
		}
		RecordKit.putDateStr(list, "add_date_time", "add_date_time_str", "yyyy-MM-dd HH:mm");
		RecordKit.putDateStr(list, "check_date_time", "check_date_time_str", "yyyy-MM-dd HH:mm");
		RecordKit.putDateStr(list, "start_date_time", "start_date_time_str", "yyyy-MM-dd HH:mm");
		RecordKit.putDateStr(list, "end_date_time", "end_date_time_str", "yyyy-MM-dd HH:mm");

		PushRecord.setPushCntToRs(list, "id", PushRecord.CONTENT_REF_TYPE_PROCUREMENT);

		renderSuccess();
	}

	@SuppressWarnings("unchecked")
	public void detail() {
		int procurementId = getParaToInt("id");

		Procurement procurement = Procurement.dao.findById(procurementId);
		setAttr("procurement", procurement);
		IndustryCategory industryCategory = IndustryCategory.dao.findById(procurement.getInt("industry_id"));
		if (industryCategory != null) {
			procurement.set("product_industry_name", industryCategory.getStr("name"));
		}
		String companyName = procurement.getStr("company_name");
		procurement.set("company_name", StringUtils.isEmpty(companyName) ? "个人采购" : companyName);

		Integer accountId = procurement.getInt("account_id");
		procurement.put("account", MemberGeneralInfo.dao.findById(accountId));
		procurement.put("company", Company.getCompanyInfoByAccountId(accountId));

		Area.setNameToM(procurement, "province_code, city_code, area_code", "province, city, area");

		ModelKit.putDateFormat(procurement, "start_date_time", "start_date_time_str", "yyyy-MM-dd HH:mm");
		ModelKit.putDateFormat(procurement, "end_date_time", "end_date_time_str", "yyyy-MM-dd HH:mm");
		ModelKit.putDateFormat(procurement, "check_date_time", "check_date_time_str", "yyyy-MM-dd HH:mm");
		ModelKit.putDateFormat(procurement, "add_date_time", "add_date_time_str", "yyyy-MM-dd HH:mm");
		ModelKit.putDateFormat(procurement, "update_date_time", "update_date_time_str", "yyyy-MM-dd HH:mm");

		String displayImgJson = procurement.getStr("display_img");
		List<String> displayImgList = (List<String>) JsonUtil.toList(displayImgJson);
		procurement.put("displayImgList", displayImgList);

		Date now = new Date();
		Date endDate = procurement.getDate("end_date_time");
		if (endDate != null && now.after(endDate)) {
			procurement.put("is_time_out", AppConst.STATUS_VAL_YES);
		} else {
			procurement.put("is_time_out", AppConst.STATUS_VAL_NO);
		}
		String product_name = procurement.getStr("product_name");
		String type = procurement.getStr("type");
		if ("PURCHASE".equals(type) && !product_name.startsWith("求购")) {// 求购
			procurement.set("product_name", "求购" + product_name);
		}
		if ("SEEK".equals(type) && !product_name.startsWith("寻求")) {// 寻求
			procurement.set("product_name", "寻求" + product_name);
		}
		renderSuccess();
	}

	public void delete() {
		int procurementId = getParaToInt("id");
		Procurement.delete(procurementId);
		String userPhone = RedisService.getApiUserPhone(getParaToInt(ApiBaseController.PARAM_API_KEY_USER_ID));
		Procurement.updateOperator(userPhone, procurementId);
		renderSuccess("删除成功");
	}

	public void checkStatusPass() {
		int procurementId = getParaToInt("id");
		String remark = getPara("remark", "").trim();
		String checkStatus = AppConst.CHECK_STATUS_PASS;

		Procurement.setCheckStatus(procurementId, checkStatus, remark);
		String userPhone = RedisService.getApiUserPhone(getParaToInt(ApiBaseController.PARAM_API_KEY_USER_ID));
		Procurement.updateOperator(userPhone, procurementId);
		renderSuccess("成功设置为已通过");
	}

	public void checkStatusFail() {
		int procurementId = getParaToInt("id");
		String remark = getPara("remark", "").trim();
		String checkStatus = AppConst.CHECK_STATUS_FAIL;

		Procurement.setCheckStatus(procurementId, checkStatus, remark);

		String userPhone = RedisService.getApiUserPhone(getParaToInt(ApiBaseController.PARAM_API_KEY_USER_ID));
		Procurement.updateOperator(userPhone, procurementId);
		renderSuccess("已设置为不通过");
	}

	@SuppressWarnings("unchecked")
	@Before(Tx.class)
	public void end() {
		int procurementId = getParaToInt("id");

		Procurement.setEnd(procurementId);

		Procurement procurement = Procurement.dao.findByIdLoadColumns(procurementId, " * ");
		String productName = procurement.getStr("product_name");
		String productDescription = procurement.getStr("product_description");

		int contentRefType = PushRecord.CONTENT_REF_TYPE_PROCUREMENT;
		List<Integer> pushRecordIdList = PushRecord.listIdBy(procurementId, contentRefType);
		if (pushRecordIdList == null || pushRecordIdList.isEmpty()) {
			renderSuccess("结束成功");
			return;
		}

		List<Integer> userIdList = PushUser.listUserIdBy(pushRecordIdList);
		if (userIdList == null || userIdList.isEmpty()) {
			renderSuccess("结束成功");
			return;
		}

		// 信鸽推送
		String content = productDescription;
		XingePushService.onEndProcurement(content, procurementId, userIdList);

		// 及时通推送
		String productDecription = procurement.getStr("product_description");
		String buyNumber = procurement.getStr("buy_number");
		String city = procurement.getStr("city");
		String displayImg = procurement.getStr("display_img");
		List<String> displayImgList = new ArrayList<>();
		Date startDateTime = procurement.getDate("start_date_time");
		Date endDateTime = procurement.getDate("end_date_time");
		if (displayImg != null && !displayImg.isEmpty()) {
			displayImgList = JsonUtil.toList(displayImg);
		}
		ProcurementDto dto = new ProcurementDto(procurementId, productName, productDecription, buyNumber, city,displayImgList, startDateTime, endDateTime);
		RongCloudService.onEndProcurement(userIdList, dto);
		String userPhone = RedisService.getApiUserPhone(getParaToInt(ApiBaseController.PARAM_API_KEY_USER_ID));
		Procurement.updateOperator(userPhone, procurementId);
		renderSuccess("结束成功");
	}

	@SuppressWarnings("unchecked")
	@Before(Tx.class)
	public void push() {
		int adminUserId = getApiUserId();
		int procurementId = getParaToInt("id");

		Procurement p = Procurement.findPushCnt((new StringBuilder(String.valueOf(procurementId))).toString());
		int push_Cnt = 0;
		if (p != null)
			push_Cnt = p.getInt("count").intValue();
		if (push_Cnt > 0) {
			renderFail("您已推送过该条采购信息了！");
			return;
		}

		Procurement procurement = Procurement.dao.findByIdLoadColumns(procurementId, " * ");
		int accountId = procurement.getInt("account_id");
		String productName = procurement.getStr("product_name");
		String productDescription = procurement.getStr("product_description");

		List<UserTag> tagListA = UserTag.listByHitting(productName, UserTag.TAG_TYPE_PUSH_TAG);
//		List<UserTag> tagListB = UserTag.listByHitting(productDescription, UserTag.TAG_TYPE_PUSH_TAG);

		// 找出符合条件的用户标签,并去重
		List<UserTag> tagList = new ArrayList<UserTag>();
		Set<Integer> userIdSet = new HashSet<Integer>();
		getUserTagToList(tagList, tagListA, userIdSet);
//		getUserTagToList(tagList, tagListB, userIdSet);

		// 数量排除自己
		int pushCnt = 0;
		for (UserTag userTag : tagList) {
			int userId = userTag.getInt("userId");
			if (userId != accountId) {
				pushCnt++;
			}
		}
		// 创建采购推送记录
		int contentRefType = PushRecord.CONTENT_REF_TYPE_PROCUREMENT;
		PushRecord pushRecord = PushRecord.create(procurementId, contentRefType, adminUserId, pushCnt);
		pushRecord.save();

		int pushRecordId = pushRecord.getInt("id");

		// 用户推送记录
		List<PushUser> pushUserList = new ArrayList<PushUser>();
		Set<Integer> hittingTagIdSet = new HashSet<>();
		for (UserTag userTag : tagListA) {
			int userId = userTag.getInt("userId");
			int tagId = userTag.getInt("id");

			if (userId != accountId && !hittingTagIdSet.contains(tagId)) {
				PushUser pushUser = PushUser.create(pushRecordId, userId, tagId);
				pushUserList.add(pushUser);

				hittingTagIdSet.add(tagId);
			}
		}

//		for (UserTag userTag : tagListB) 
//		{
//			int userId = userTag.getInt("userId");
//			int tagId = userTag.getInt("id");
//
//			if (userId != accountId && !hittingTagIdSet.contains(tagId))
//			{
//				PushUser pushUser = PushUser.create(pushRecordId, userId, tagId);
//				pushUserList.add(pushUser);
//				
//				hittingTagIdSet.add(tagId);
//			}
//		}
		// 用户标签ID
		List<Integer> userTagIdList = new ArrayList<Integer>();
		List<Integer> userIdList = new ArrayList<Integer>();
		// List<PushUser> pushUserList = new ArrayList<PushUser>();
		Map<String, List<Integer>> tagToUserListMap = new HashMap<>();
		for (UserTag userTag : tagList) {
			int userId = userTag.getInt("userId");
			int tagId = userTag.getInt("id");

			if (userId != accountId) {
				// PushUser pushUser = PushUser.create(pushRecordId, userId, tagId);

				// pushUserList.add(pushUser);
				userTagIdList.add(tagId);
				userIdList.add(userId);

				String tagTitle = userTag.getStr("title");
				if (!tagToUserListMap.containsKey(tagTitle)) {
					tagToUserListMap.put(tagTitle, new ArrayList<Integer>());
				}
				tagToUserListMap.get(tagTitle).add(userId);
			}
		}
		// 保存用户推送记录
		PushUser.dao.saveList(pushUserList);
		// 用户标签增加次数
		UserTag.plusUseCnt(userTagIdList);
		// 用户减去推送次数
		PushNum.minusNum(userIdList);

		// 信鸽推送
		String content = productDescription;

		XingePushService.onPushProcurement(content, procurementId, userIdList);

		// 及时通推送
		String productDecription = procurement.getStr("product_description");
		String buyNumber = procurement.getStr("buy_number");
		String city = procurement.getStr("city");
		String displayImg = procurement.getStr("display_img");
		List<String> displayImgList = new ArrayList<>();
		Date startDateTime = procurement.getDate("start_date_time");
		Date endDateTime = procurement.getDate("end_date_time");
		if (displayImg != null && !displayImg.isEmpty()) {
			displayImgList = JsonUtil.toList(displayImg);
		}
		ProcurementDto dto = new ProcurementDto(procurementId, productName, productDecription, buyNumber, city,
				displayImgList, startDateTime, endDateTime);
		RongCloudService.onPushProcurement(userIdList, dto);

		// 短信推送
		SnsPushService.pushProcurement(tagToUserListMap);

		String userPhone = RedisService.getApiUserPhone(getParaToInt(ApiBaseController.PARAM_API_KEY_USER_ID));
		Procurement.updateOperator(userPhone, procurementId);
		renderSuccess("提交成功，正在推送");
	}

	/**
	 * 撤销推送
	 */
	@Before(Tx.class)
	public void recallPush() {
		int procurementId = getParaToInt("id");
		Procurement p = Procurement.findPushCnt((new StringBuilder(String.valueOf(procurementId))).toString());
		int push_Cnt = 0;
		if (p != null)
			push_Cnt = p.getInt("count").intValue();
		if (push_Cnt == 0) {
			renderFail("该条采购未推送过，无法撤销");
			return;
		}
		PushRecord pushRecord = PushRecord.findByProcurementId(procurementId);
		int pushRecordId = pushRecord.getInt("id");

		List<PushUser> pushUsers = PushUser.dao.find("select * from push_user pu WHERE pu.pushRecordId = ?",
				pushRecordId);

		List<Integer> userTagIdList = new ArrayList<Integer>();
		List<Integer> userIdList = new ArrayList<Integer>();
		for (PushUser pushUser : pushUsers) {
			userTagIdList.add(pushUser.getInt("tagId"));
			userIdList.add(pushUser.getInt("userId"));
		}
		// 用标签减数量
		UserTag.minusUseCnt(userTagIdList);
		// 用户推送次数加数量
		PushNum.plusNum(userIdList);
		// 删除用户推送记录
		Db.delete("delete from push_user where pushRecordId = ?", pushRecordId);
		// 删除采购推送记录
		Db.delete("delete from push_record where contentRefId = ? and contentRefType = ? ", procurementId,
				PushRecord.CONTENT_REF_TYPE_PROCUREMENT);

		String userPhone = RedisService.getApiUserPhone(getParaToInt(ApiBaseController.PARAM_API_KEY_USER_ID));
		Procurement.updateOperator(userPhone, procurementId);
		renderSuccess("提交成功，正在推送");
	}

	private void getUserTagToList(List<UserTag> toList, List<UserTag> fromList, Set<Integer> userIdSet) {
		for (UserTag userTag : fromList) {
			int userId = userTag.getInt("userId");
			if (!userIdSet.contains(userId)) {
				toList.add(userTag);
				userIdSet.add(userId);
			}
		}
	}

	public void pushList() {

		String keyWord = getPara("keyWord", "").trim();
		int contentRefType = PushRecord.CONTENT_REF_TYPE_PROCUREMENT;
		// 排序
		String columnProp = getPara("columnProp", "").trim();
		String columnOrder = getPara("columnOrder", "").trim().split("ending")[0];
		System.out.println("columnProp==>" + columnProp);
		System.out.println("columnOrder==>" + columnOrder);

		String select = " select pr.createTime, pr.pushCnt, "
				+ " p.id, p.company_name, p.address, p.contact_name, p.contact_phone, p.contact_email, "
				+ " p.product_name, p.product_description, p.buy_number, p.product_industry_name, p.product_specification, p.start_date_time, p.end_date_time, p.add_date_time ,IF(p.end_date_time < NOW(),1,0) is_time_out ";
		String where = " from push_record pr inner join bbs_procurement p on p.id = pr.contentRefId "
				+ " where pr.contentRefType = ? ";
		String orderBy = "";
		if (!columnOrder.isEmpty()) {
			switch (columnProp) {
			case "is_time_out_time":
				orderBy = " order by p.end_date_time " + columnOrder;
				break;
			case "add_date_time_str":
				orderBy = " order by p.add_date_time " + columnOrder;
				break;
			case "is_time_out":
				orderBy = " order by is_time_out " + columnOrder;
				break;
			case "createTimeStr":
				orderBy = " order by pr.createTime " + columnOrder;
				break;
			}
		} else {
			orderBy = " order by pr.createTime desc ";
		}

		List<Object> params = new ArrayList<Object>();
		params.add(contentRefType);
		if (!keyWord.isEmpty()) {
			where += " and ( p.company_name like ? or p.contact_phone like ? or p.product_name like ?)";
			String keyWordParam = "%" + keyWord + "%";
			params.add(keyWordParam);
			params.add(keyWordParam);
			params.add(keyWordParam);
		}

		Page<Record> page = page(select, where + orderBy, params.toArray());
		List<Record> list = page.getList();
		RecordKit.putDateStr(list, "start_date_time", "start_date_time_str", "yyyy-MM-dd HH:mm");
		RecordKit.putDateStr(list, "end_date_time", "end_date_time_str", "yyyy-MM-dd HH:mm");
		RecordKit.putDateStr(list, "add_date_time", "add_date_time_str", "yyyy-MM-dd HH:mm");
		RecordKit.putDateStr(list, "createTime", "createTimeStr", "yyyy-MM-dd HH:mm");

		renderSuccess();
	}

}
